using AspectCore.Configuration;
using AspectCore.Extensions.DependencyInjection;
using Ldt.SettingCenter.Core;
using LdtCommonLibraryAop;
using LdtCommonLibraryHttp;
using LdtCommonUtil;
using LdtCommonUtil.DependencyExd;
using LdtCommonUtil.JsonConfig;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.OpenApi.Models;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using ManageModel.Webapi.Middlewares;
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;

namespace ManageModel.Webapi
{
    /// <summary>
    /// Startup
    /// </summary>
    public class Startup
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="Startup"/> class.
        /// </summary>
        /// <param name="configuration">The configuration.</param>
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }
        /// <summary>
        /// Gets the configuration.
        /// </summary>
        /// <value>
        /// The configuration.
        /// </value>
        public IConfiguration Configuration { get; }
        /// <summary>
        /// Configures the services.
        /// </summary>
        /// <param name="services">The services.</param>
        public void ConfigureServices(IServiceCollection services)
        {
            InitService(services);
            //全局拦截器（每个接口上就不需要加StatisticalTimeInterceptorAttribute了）
            services.ConfigureDynamicProxy(config =>
            {
                config.Interceptors.AddTyped<LogAttribute>(args: new object[] { NLog.LogLevel.Info, false }, Predicates.ForService("*HttpHelper"));
            });
            services.AddSingleton<ISettingCenter>(
                 con =>
                 {
                     var config = con.GetService<IConfiguration>();
                     var httphelp = con.GetService<IHttpHelper>();
                     return new SettingCenterClient(config.GetSection("SettingCenter").Value, config.GetSection("ProductCode").Value, httphelp);
                 }
             );
            services.AddHttpClient().AddSingleton<IHttpHelper, HttpHelper>();
        }
        /// <summary>
        /// Initializes the service.一些通用的初始化
        /// </summary>
        /// <param name="services">The services.</param>
        private void InitService(IServiceCollection services)
        {
            System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance);//解决GBK编码问题
                                                                                                  //services.AddRouting(options => options.LowercaseUrls = true);//url地址小写
            services.Configure<ApiBehaviorOptions>(options =>
            {
                options.SuppressModelStateInvalidFilter = true;
            });
            services.AddControllers(options =>
            {
                options.Filters.Add<HttpResponseExceptionFilter>();
                options.Filters.Add<ValidFilter>();
            }).AddNewtonsoftJson(options =>
            {
                //修改属性名称的序列化方式，首字母小写
                options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
                //修改时间的序列化方式
                options.SerializerSettings.Converters.Add(new MultiFormatDateConverter()
                {
                    DateTimeFormats = new List<string> { "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd", "yyyy-MM-ddTHH:mm:ss", "yyyy-MM-ddTHH:mm:ssZ", "yyyy-MM-ddTHH:mm:sssZ", "yyyy-MM-ddTHH:mm:ss.fffZ" }
                });
                //空的字段不返回
                options.SerializerSettings.NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore;
                JsonConvert.DefaultSettings = new Func<JsonSerializerSettings>(() =>
                {
                    return options.SerializerSettings;
                });
            });//使用Newton替换默认的text.json
               //.AddControllersAsServices();//control可以被aspect切面
            services.AddCors(options => options.AddPolicy("AllowAllOrigins",
                  builder =>
                  {
                      builder.AllowAnyMethod()
                          .SetIsOriginAllowed(_ => true)
                          .AllowAnyHeader()
                          .AllowCredentials();
                  }));//运行跨域配置
            services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new OpenApiInfo { Title = $"{nameof(ManageModel.Webapi)} API接口", Version = "v1" });
                // Set the comments path for the Swagger JSON and UI.
                var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
                var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
                c.IncludeXmlComments(xmlPath);
                c.OperationFilter<FileUploadOperation>();
            });//Swagger
            services.AutoInJectionAllClass(AssemblyHelper.GetAssemblies("LdtCommon*.dll", new List<string> { "LdtCommonUtil.dll" }));
            services.AutoInJectionAllClass(AssemblyHelper.GetAssemblies($"{nameof(ManageModel)}.{nameof(ManageModel.Bll)}.dll"));
            services.AddHostedService<LifetimeEventsHostedService>();
        }
        /// <summary>
        /// Configures the specified application.
        /// </summary>
        /// <param name="app">The application.</param>
        /// <param name="env">The env.</param>
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            ////app.UseMiddleware<HttpResponseExceptionMiddleware>();
            ServiceProviderInstance.Instance = app.ApplicationServices;
            #region Swagger
            // Enable middleware to serve generated Swagger as a JSON endpoint.
            app.UseSwagger();
            // Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.),
            // specifying the Swagger JSON endpoint.
            app.UseSwaggerUI(c =>
            {
                c.SwaggerEndpoint("/swagger/v1/swagger.json", $"{nameof(ManageModel)}.Webapi V1");
                c.RoutePrefix = "ldt";
            });
            #endregion

            app.UseRouting();
            app.UseAuthorization();
            app.UseCors("AllowAllOrigins");//跨域操作
            app.UseStaticFiles();


            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
    }
}
